﻿//  Copyright (c) 2010 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;

namespace DNA.Mvc
{
    public abstract class ViewComponentBuilder<TComponent,TBuilder>
        where TComponent:ViewComponent
        where TBuilder:ViewComponentBuilder<TComponent,TBuilder>
    {
        private TComponent component;

        public TComponent Component
        {
            get { return component; }
            private set { component = value; }
        }

        public IViewDataContainer ViewDataContainer
        {
            get
            {
                return component.ViewDataContainer;
            }
        }

        public ViewContext ViewContext
        {
            get
            {
                return component.ViewContext;
            }
        }

        private AjaxHelper _ajaxHelper;

        protected AjaxHelper Helper
        {
            get
            {
                if (_ajaxHelper == null)
                    _ajaxHelper = new AjaxHelper(this.ViewContext, this.ViewDataContainer);
                return _ajaxHelper;
            }
        }

        public ViewComponentBuilder(TComponent component, ViewContext context,IViewDataContainer container)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            Component = component;
            Component.ViewContext = context;
            Component.ViewDataContainer = container;
        }

        public TBuilder GenerateId()
        {
            if (string.IsNullOrEmpty(Component.Name))
            {
                string prefix= Component.GetType().Name;
                string key = "DJME_IDSEQ_" +prefix;
                int seq = 1;

                if (ViewContext.HttpContext.Items.Contains(key))
                {
                    seq = (int)ViewContext.HttpContext.Items[key] + 1;
                    ViewContext.HttpContext.Items[key] = seq;
                }
                else
                    ViewContext.HttpContext.Items.Add(key, seq);
                Component.Name = prefix + seq.ToString();
            }

            return this as TBuilder;
        }

        public virtual TBuilder Name(string name)
        {
            Component.Name = name;
            return this as TBuilder;
        }

        public virtual TBuilder AddClass(string className)
        {
            Component.MergeAttribute("class", className);
            return this as TBuilder;
        }

        public virtual TBuilder StyleText(string cssText)
        { 
            Component.MergeAttribute("style",cssText);
            return this as TBuilder;
        }

        public virtual TBuilder Width(int width) 
        {
            Component.Width = width;
            //Component.MergeAttribute("style", "width:" + width.ToString() + "px;"+(Component.Height>0 ? Component.Height.ToString()+"px;":""));
            return this as TBuilder;
        }

        public virtual TBuilder Height(int height)
        {
            Component.Height = height;
            //Component.MergeAttribute("style", "height:" + height.ToString() + "px");
            return this as TBuilder;
        }

        public virtual TBuilder MergeAttribute(string key, object value)
        {
            //if (Component.HtmlAttributes.ContainsKey(key))
            //    Component.HtmlAttributes[key] =Component.HtmlAttributes[key]+" "+value.ToString();
            //else
            //    Component.HtmlAttributes.Add(key, value.ToString());
            Component.MergeAttribute(key, value.ToString());
            return this as TBuilder;
        }

        public virtual TBuilder HtmlAttributes(object htmlAttributes)
        {
            var attributes = ObjectHelper.ConvertObjectToDictionary(htmlAttributes);
            //foreach (var key in attributes.Keys)
            Component.MergeAttributes(attributes);
            return this as TBuilder;
        }

        public virtual TBuilder ToolTip(string title)
        {
            MergeAttribute("title", title);
            return this as TBuilder;
        }

        public virtual void Render()
        {
            RenderComponent();
        }

        protected void RenderComponent()
        {
            using (var writer = new HtmlTextWriter(ViewContext.Writer))
            {
                Component.Render(writer);
            }
        }

        public virtual MvcHtmlString GetHtml()
        {
            return MvcHtmlString.Create(Component.GetHtml());
        }

    }
}